In many information processing applications, multiple executing entities attempt to access data concurrently. In one example, in an email application, multiple processes may attempt to access emails, profiles, stores, and other related data at the same time. In this case, a single program executes multiple threads concurrently accessing the same data. In another example, in a database application, multiple users may attempt to access the same database tables, records, and fields at the same time. In this case, multiple programs operated by multiple users may concurrently access the same data. As used herein, an entity may refer to processes, threads, tasks, processors, programming objects, and the like.
Concurrent access to the same data, if left uncontrolled, can potentially lead to data corruption. For example, consider the following scenario in which two computers, A and B, both attempt to remove one item from inventory by subtracting one from an inventory field in a database:
1. The initial inventory field value is two.
2. Computer A reads the inventory field value (two) to its local storage value.
3. Computer B reads the inventory field value (two) to its local storage value.
4. Computer A subtracts one from its local storage value (two), yielding a new local storage value of one.
5. Computer B subtracts one from its local storage value (two), yielding a new local storage value of one.
6. Computer A writes its local storage value (one) to the inventory field value.
7. Computer B writes its local storage value (one) to the inventory field.
8. The final inventory field value is one.
As indicated above, the final inventory field value is one. However, it is clear that the final inventory field value should be zero because two items have been removed from inventory. The illustrated scenario shows that two or more entities concurrently accessing the same data value may corrupt the value, potentially leading to disastrous consequences.
Programmers have advanced a variety of approaches to address problems arising from concurrent processing. On a general level, many programming systems provide synchronization services to provide certain guarantees in light of potential concurrency issues. For example, some programming environments support simple synchronization mechanisms such as semaphores, locks, critical sections, and mutual exclusion objects (“mutexes” or “mutex objects”). Each of these mechanisms controls, in one form or another, concurrent access to a shared resource. Examples of mutex objects include mutex objects, an implementation of which is provided as part of the WIN32 application programming interface within the WINDOWS operating system also from MICROSOFT CORPORATION. Many WINDOWS-based programs, such as email and database computer applications, utilize these mutex objects for synchronizing access to various shared data.
Mutex objects synchronize access to a shared resource, such as shared memory, from multiple processes executing on a single machine. Generally, mutex objects are kernel objects. A kernel object is a memory block allocated by the kernel and is accessible only by the kernel. As such, computer applications operating in user mode are typically transitioned to kernel mode before mutex objects can be utilized. This transition between user mode and kernel mode can result in significant overall performance cost, especially when mutex objects are often utilized.
It is with respect to these considerations and others that the disclosure made herein is presented.